﻿namespace Home
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;

    public class BidEngine
    {
        private readonly string accountsFileName;
        private readonly string accountsFileFieldSeparator;

        public BidEngine(string accountsFileName = null, string accountsFileFieldSeparator = null)
        {
            Debug.Assert(accountsFileName == null || accountsFileName.Length > 0);

            if (accountsFileName == null)
            {
                accountsFileName = BidConfiguration.AccountsCsvFileName;
            }

            if (accountsFileFieldSeparator==null)
            {
                this.accountsFileFieldSeparator = BidConfiguration.AccountsCsvFileFieldSeparator;
            }
        }

        public event EventHandler<BidAccountsFileLoadEventArgs> LoadingAccountsFile;
        public event EventHandler<BidAccountsFileLoadEventArgs> LoadedAccountsFile;

        public async Task RunAsync()
        {
            var accounts = await LoadAccountsAsync();

            foreach (var account in accounts)
            {

            }
        }

        protected virtual void OnLoadingAccountsFile(BidAccountsFileLoadEventArgs args)
        {
            if (this.LoadingAccountsFile != null)
            {
                this.LoadingAccountsFile(this, args);
            }
        }

        protected virtual void OnLoadedAccountsFile(BidAccountsFileLoadEventArgs args)
        {
            if (this.LoadedAccountsFile != null)
            {
                this.LoadedAccountsFile(this, args);
            }
        }

        private async Task<IEnumerable<BidAccount>> LoadAccountsAsync()
        {
            var result = new List<BidAccount>();

            OnLoadingAccountsFile(new BidAccountsFileLoadEventArgs(this.accountsFileName, BidAccountsFileStatus.Loading));

            try
            {
                using (var reader = new StreamReader(this.accountsFileName, Encoding.UTF8, true))
                {
                    var index = 0;
                    var line = default(string);
                    while ((line = await reader.ReadLineAsync()) != null)
                    {
                        var fields = line.Split(new[] { this.accountsFileFieldSeparator }, StringSplitOptions.RemoveEmptyEntries);
                        if (fields.Length < 4)
                        {
                            throw new BidException("The format at line {0} is wrong. The line content is <{1}>.", index + 1, line);
                        }

                        result.Add(new BidAccount(
                            name: fields[0].Trim(),
                            idCardNumber: fields[1].Trim(),
                            bidNumber: fields[2].Trim(),
                            bidPassword: fields[3].Trim()));

                        ++index;
                    }
                }
            }
            catch (BidException)
            {
                OnLoadedAccountsFile(new BidAccountsFileLoadEventArgs(this.accountsFileName, BidAccountsFileStatus.LoadedFailed));
                throw;
            }
            catch (Exception ex)
            {
                OnLoadedAccountsFile(new BidAccountsFileLoadEventArgs(this.accountsFileName, BidAccountsFileStatus.LoadedFailed));
                throw new BidException("Load accounts file <{0}> was failed.", ex, this.accountsFileName);
            }

            OnLoadedAccountsFile(new BidAccountsFileLoadEventArgs(this.accountsFileName, BidAccountsFileStatus.LoadedSuccessful));

            return result;
        }
    }
}
